package com.luyuan.crm.member.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.luyuan.crm.member.model.Customer;
import com.luyuan.crm.member.model.Member;
import com.luyuan.crm.member.model.MemberIntegral;
import com.luyuan.crm.member.model.MemberLiveness;
import com.luyuan.crm.member.model.MemberLoyalty;
import com.luyuan.crm.member.service.MemberService;
import com.luyuan.crm.user.Party;
import com.luyuan.crm.user.service.PartyService;
import com.ruijie.components.security.model.AppUser;
import com.ruijie.components.security.model.Role;
import com.ruijie.components.security.service.AppUserService;
import com.ruijie.components.security.service.RoleService;
import com.ruijie.components.setting.Setting;
import com.ruijie.components.setting.service.SettingService;
import com.ruijie.foundation.dao.support.HibernateEntityDao;
import com.ruijie.foundation.query.Page;
import com.ruijie.foundation.query.criteria.CriteriaQueryTemplate;
import com.ruijie.foundation.query.criteria.CriteriaTemplate;
import com.ruijie.foundation.query.criteria.RestrictionTemplate;

public class MemberServiceImpl extends HibernateEntityDao<Member> implements MemberService {

    private AppUserService appUserService;

    private RoleService roleService;

    private PartyService partyService;

    private SettingService settingService;

    @Override
    public Member getByName(String name) {
        Member member = this.findUniqueBy("memName", name);
        return member;
    }

    @Override
    public Page pagedQuery(CriteriaTemplate criteria, int page, int pageSize, List<Order> orders) {
        CriteriaQueryTemplate qt = new CriteriaQueryTemplate(getSessionFactory());
        return qt.pagedQuery(criteria, page, pageSize, orders);
    }

    @Override
    public Member createMember(Customer customer, Party sale) {
        // 将客户转成会员
        // getHibernateTemplate().executeWithNewSession(new HibernateCallback() {
        // @Override
        // public Object doInHibernate(Session session) throws HibernateException, SQLException {
        // session.beginTransaction();
        updateBySQL("customer.updateCustomerType", new String[] { "member", customer.getId() });
        // session.getTransaction().commit();
        // return null;
        // }
        // });
        evit(customer);

        // 创建帐号
        AppUser user = new AppUser();
        user.setUsername(customer.getMobile());
        user.setPassword("88888888");
        Set<Role> roles = new HashSet<Role>();
        Role role = roleService.findRoleByName("会员");
        roles.add(role);
        user.setRoles(roles);
        appUserService.addUser(user);
        flush();

        // 更新会员资料
        Member member = findUniqueBy("id", customer.getId());

        member.setCreateTime(new Date());
        member.setActiveTime(new Date());
        member.setLiveness(MemberLiveness.COMMONLY);
        member.setLoyalty(MemberLoyalty.INTENTION);
        user = appUserService.findUserByLoginName(user.getUsername());
        member.setAccount(user);
        member.setSupport(null);
        // 会员归属由第一次下单的人决定
        member.setBranchOffice(sale.getBranchOffice());

        MemberIntegral memberIntegral = new MemberIntegral();
        member.setMemberIntegral(memberIntegral);
        memberIntegral.setMember(member);
        memberIntegral.setCurrentIntegral(0);
        memberIntegral.setDiscount(1);
        memberIntegral.setTotalIntegral(0);
        update(member);

        // 指派售后
        Party party = findNextParty(sale);
        member.setSupport(party);

        return member;
    }

    private Party findNextParty(Party sale) {
        getSession().refresh(sale);
        Set<Role> roles = sale.getAppUser().getRoles();
        for (Role role : roles) {
            // 对于售后下的订单，归属售后自身
            if (role.getRoleName().startsWith("售后")) {
                return sale;
            }
        }

        Party party = null;

        int i = 0;
        Setting setting = settingService.getSetting("crm.member.party");
        do {
            CriteriaTemplate c = CriteriaTemplate.forClass(Party.class);
            RestrictionTemplate r = new RestrictionTemplate(true);
            c.createCriteria("appUser", "user").createCriteria("user.roles", "role");
            c.add(r.gt("id", setting.getValue()));
            c.add(Restrictions.in("role.roleName", new String[] { "售后经理", "售后" }));
            c.add(r.eq("user.enabled", Boolean.TRUE));
            c.add(r.ne("user.username", settingService.getSetting("crm.member.support.excluded").getValue()));

            List<Order> orders = new ArrayList<Order>();
            orders.add(Order.asc("id"));
            Page page = partyService.pagedQuery(c, 1, 1, orders);
            if (page.getTotalCount() > 0) {
                party = (Party) ((List<?>) page.getResult()).get(0);
            }
            setting.setValue("0");
        } while (party == null && (i++) < 5);

        if (party != null) {
            setting.setValue(party.getId());
        }
        settingService.updateSetting(setting);
        return party;
    }

    @Override
    public void updateMember(Member member) {
        super.update(member);
    }

    @Override
    public void updateActiveTime(Member member) {
        member.setActiveTime(new Date());
        super.update(member);
    }

    @Override
    public Member getByAccount(AppUser appUser) {
        Member member = findUniqueBy("account", appUser);
        return member;
    }

    @Override
    public Page pagedQueryOnline(CriteriaTemplate criteria, int page, int pageSize, List<Order> orders) {
        CriteriaQueryTemplate qt = new CriteriaQueryTemplate(getSessionFactory());
        return qt.pagedQuery(criteria, page, pageSize, orders);
    }

    public void setAppUserService(AppUserService appUserService) {
        this.appUserService = appUserService;
    }

    public void setRoleService(RoleService roleService) {
        this.roleService = roleService;
    }

    @Override
    public List<Member> findByParty(Party party) {
        return findBy("customerService", party);
    }

    @Override
    public Member getById(String id) {
        return super.safeGet(id);
    }

    @Override
    public Member getByMobile(String mobile) {
        return findUniqueBy("mobile", mobile);
    }

    public void setSettingService(SettingService settingService) {
        this.settingService = settingService;
    }

    public void setPartyService(PartyService partyService) {
        this.partyService = partyService;
    }
}
